import 'package:flutter/material.dart';
import 'package:flutter_utils/flutter_utils.dart';
import 'package:flutter_widget/src/config/color_define.dart';
import 'package:flutter_widget/src/config/config.dart';
import 'package:flutter_widget/src/widget/button/go_back_button.dart';
import 'package:flutter_widget/src/widget/text/text_format.dart';

///shrinkOffset 偏移量,最大为maxHeight; alpha根据偏移量计算的透明度变化参考值0~255
typedef SliverHeaderTopBar = Widget Function(double shrinkOffset, int alpha);
typedef SliverHeaderBody = Widget Function(double shrinkOffset, int alpha);
typedef SliverHeaderTitle = Widget Function(double shrinkOffset, int alpha);

enum SliverHeaderWidgetStatusColor {
  light,
  dark, //字体显示黑色
}

class SliverHeaderWidget<T extends ChangeNotifier> extends StatelessWidget {
  final double maxHeight; //最大高度
  final double minHeight; //最小高度
  final double? minTransitionHeight; //变化的最小过渡距离，不能超过maxHeight
  final SliverHeaderBody? body; //中间一整块，可设置背景之类

  //以下不传只有body
  final String? title; //设置标题
  final SliverHeaderTitle? titleWidget; //设置标题Widget, 如果设置，则title不生效
  final Color? titleBgColor; //标题背景色
  final SliverHeaderTopBar? topBar; //顶部栏，如果设置了则titleWidget不生效
  final IconButton? action; //右边按键
  final Widget? bottom; //底部，如果有的话
  final double bottomHeight; //底部高度
  final double? displayTextOffset; //标题显示变化的最小偏移距离
  final SliverHeaderWidgetStatusColor defaultStatusColor; //默认状态栏字体颜色,默认light
  final SliverHeaderWidgetStatusColor transitionStatusColor; //状态栏字体过渡颜色，默认dark

  const SliverHeaderWidget({
    Key? key,
    this.title,
    this.maxHeight = 250,
    this.minHeight = 44,
    this.body,
    this.topBar,
    this.titleWidget,
    this.titleBgColor,
    this.action,
    this.displayTextOffset = 0,
    this.minTransitionHeight,
    this.bottom,
    this.bottomHeight = 0,
    this.defaultStatusColor = SliverHeaderWidgetStatusColor.light,
    this.transitionStatusColor = SliverHeaderWidgetStatusColor.dark,
  }) : super(key: key);

  @override
  Widget build(BuildContext context) {
    return SliverPersistentHeader(
      pinned: true, //固定在顶部
      floating: false, //不随着滑动隐藏顶部
      delegate: SliverHeaderDelegate(
        title: title,
        maxHeight: maxHeight,
        minHeight: minHeight,
        body: body,
        topBar: topBar,
        titleWidget: titleWidget,
        titleBgColor: titleBgColor ?? Colors.white,
        action: action,
        displayTextOffset: displayTextOffset ?? 0,
        minTransitionHeight: minTransitionHeight ?? 100,
        bottom: bottom,
        bottomHeight: bottomHeight,
        defaultStatusColor: defaultStatusColor,
        transitionStatusColor: transitionStatusColor,
      ),
    );
  }
}

class SliverHeaderDelegate<T extends ChangeNotifier>
    extends SliverPersistentHeaderDelegate {
  SliverHeaderWidgetStatusColor? _statusBarMode;

  double maxHeight; //最大高度
  double minHeight; //最小高度
  double minTransitionHeight; //最小过渡距离
  SliverHeaderBody? body; //中间一整块，可设置背景之类

  //以下不传只有body
  String? title; //设置标题
  SliverHeaderTitle? titleWidget; //设置标题Widget, 如果设置，则title不生效
  SliverHeaderTopBar? topBar; //顶部栏，如果设置了则titleWidget不生效
  Color titleBgColor; //标题背景色
  double displayTextOffset;
  IconButton? action; //右边按键
  Widget? bottom; //底部，如果有的话
  double bottomHeight; //底部高度
  SliverHeaderWidgetStatusColor defaultStatusColor; //默认状态栏字体颜色
  SliverHeaderWidgetStatusColor transitionStatusColor; //状态栏字体过渡颜色

  SliverHeaderDelegate({
    this.title,
    required this.maxHeight,
    this.minHeight = 44,
    this.body,
    this.topBar,
    this.titleWidget,
    this.titleBgColor = Colors.white,
    this.action,
    this.displayTextOffset = 30,
    this.minTransitionHeight = 100,
    this.bottom,
    this.bottomHeight = 0,
    this.defaultStatusColor = SliverHeaderWidgetStatusColor.light,
    this.transitionStatusColor = SliverHeaderWidgetStatusColor.dark,
  }) : super();

  @override
  double get maxExtent => (maxHeight > minHeight ? maxHeight : minHeight);

  @override
  double get minExtent => minHeight;

  @override
  bool shouldRebuild(covariant SliverHeaderDelegate oldDelegate) {
    return titleBgColor != oldDelegate.titleBgColor ||
        maxHeight != oldDelegate.maxHeight ||
        minHeight != oldDelegate.minHeight ||
        title != oldDelegate.title ||
        titleWidget != oldDelegate.titleWidget ||
        topBar != oldDelegate.topBar ||
        body != oldDelegate.body; //runtimeType != oldDelegate.runtimeType ||
  }

  void _updateStatusBarBrightness(shrinkOffset) {
    if (shrinkOffset > minTransitionHeight / 2 &&
        _statusBarMode != transitionStatusColor) {
      _statusBarMode = transitionStatusColor;
      // debugPrint("shrinkOffset > (minTransitionHeight ?? 100) $shrinkOffset _statusBarMode${_statusBarMode}");
      if (_statusBarMode == SliverHeaderWidgetStatusColor.light) {
        StatusBarUtil.setupTextStyle(isDark: false);
      } else {
        StatusBarUtil.setupTextStyle(isDark: true);
      }
    } else if (shrinkOffset <= minTransitionHeight / 2 &&
        _statusBarMode != defaultStatusColor) {
      _statusBarMode = defaultStatusColor;
      // debugPrint("shrinkOffset <= (minTransitionHeight ?? 100) $shrinkOffset _statusBarMode${_statusBarMode}");
      if (_statusBarMode == SliverHeaderWidgetStatusColor.light) {
        StatusBarUtil.setupTextStyle(isDark: false);
      } else {
        StatusBarUtil.setupTextStyle(isDark: true);
      }
    } else {
      // debugPrint("shrinkOffset $shrinkOffset _statusBarMode${_statusBarMode}");
    }
  }

  //逐渐变化透明度
  int _getAlpha(shrinkOffset) {
    double changeHeight = maxExtent;
    if (minTransitionHeight < maxExtent) {
      changeHeight = minTransitionHeight;
    }
    final int? alpha =
        (shrinkOffset / changeHeight * 255).clamp(0, 255).toInt();
    return alpha ?? 0;
  }

  Color _makeStickyHeaderBgColor(shrinkOffset) {
    int alpha = _getAlpha(shrinkOffset);
    return titleBgColor.withAlpha(alpha);
  }

  Color _makeStickyHeaderTextColor(shrinkOffset) {
    if (displayTextOffset > 0) {
      if (shrinkOffset <= displayTextOffset) {
        return FWColorPicker.clear;
      } else {
        int alpha = _getAlpha(shrinkOffset);
        return Color.fromARGB(alpha, 0, 0, 0);
      }
    } else {
      return _makeStickyHeaderBackColor(shrinkOffset);
    }
  }

  Color _makeStickyHeaderBackColor(shrinkOffset) {
    int alpha = _getAlpha(shrinkOffset);
    int num = 255 - alpha;
    return Color.fromARGB(255, num, num, num);
  }

  Widget _topBar(BuildContext context, shrinkOffset) {
    return Positioned(
      left: 0,
      right: 0,
      top: 0,
      child: topBar != null
          ? topBar!(shrinkOffset, _getAlpha(shrinkOffset))
          : Container(
              color: _makeStickyHeaderBgColor(shrinkOffset),
              // padding: EdgeInsets.only(top: Screens.topSafeHeight),
              child: SafeArea(
                top: true,
                bottom: false,
                child: Column(
                  mainAxisSize: MainAxisSize.min,
                  children: [
                    SizedBox(
                      height: minExtent - (Screens.topSafeHeight + bottomHeight),
                      child: Row(
                        mainAxisAlignment: MainAxisAlignment.center,
                        children: <Widget>[
                          Expanded(
                            flex: 1,
                            child: Align(
                              alignment: Alignment.centerLeft,
                              child: SizedBox(
                                width: 50,
                                height: minExtent - Screens.topSafeHeight - bottomHeight,
                                child: GoBackButton(
                                  iconColor:
                                      _makeStickyHeaderBackColor(shrinkOffset),
                                ),
                              ),
                            ),
                          ),
                          Center(
                            child: titleWidget != null
                                ? titleWidget!(
                                    shrinkOffset,
                                    _getAlpha(shrinkOffset),
                                  )
                                : TextFormatWidget(title,
                                    fontSize: 17,
                                    fontWeight: FWConfig.isIOS == true
                                        ? FontWeight.w500
                                        : FontWeight.w600,
                                    color: _makeStickyHeaderTextColor(
                                        shrinkOffset)),
                          ),
                          (action != null)
                              ? Expanded(
                                  flex: 1,
                                  child: Align(
                                    alignment: Alignment.centerRight,
                                    child: DefaultTextStyle(
                                      style: TextStyle(
                                        fontSize: 13,
                                        color: _makeStickyHeaderTextColor(
                                            shrinkOffset),
                                      ),
                                      overflow: TextOverflow.ellipsis,
                                      child: SizedBox(
                                        width: 60,
                                        child: action,
                                      ),
                                    ),
                                  ),
                                )
                              : const Spacer(),
                        ],
                      ),
                    ),
                    Container(
                      height: 0.5,
                      color: FWColorPicker.grayLine
                          .withAlpha(_getAlpha(shrinkOffset)),
                    )
                  ],
                ),
              ),
            ),
    );
  }

  Widget _body(double shrinkOffset) {
    return Positioned(
      top: -shrinkOffset,
      left: 0,
      right: 0,
      height: maxHeight - bottomHeight,
      child: body != null
          ? body!(shrinkOffset, _getAlpha(shrinkOffset))
          : Container(),
    );
  }

  Widget _bottom(double shrinkOffset) {
    return Positioned(
      bottom: 0,
      left: 0,
      right: 0,
      height: bottomHeight,
      child: bottom != null ? bottom! : Container(),
    );
  }

  @override
  Widget build(
      BuildContext context, double shrinkOffset, bool overlapsContent) {
    if (title == null && titleWidget == null && topBar == null) {
      _updateStatusBarBrightness(shrinkOffset);
      return SizedBox(
        height: maxExtent,
        width: MediaQuery.of(context).size.width,
        child: Stack(
          fit: StackFit.expand,
          children: <Widget>[
            body != null
                ? body!(shrinkOffset, _getAlpha(shrinkOffset))
                : Container(),
            if (bottom != null) _bottom(shrinkOffset),
          ],
        ),
      );
    } else {
      _updateStatusBarBrightness(shrinkOffset);
      return SizedBox(
        height: maxExtent,
        width: MediaQuery.of(context).size.width,
        child: Stack(
          fit: StackFit.expand,
          children: <Widget>[
            _body(shrinkOffset),
            _topBar(context, shrinkOffset),
            if (bottom != null) _bottom(shrinkOffset),
          ],
        ),
      );
    }
  }
}
